package com.rex.saas.controller;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.rex.saas.bean.*;
import com.rex.saas.bean.request.*;
import com.rex.saas.bean.response.*;
import com.rex.saas.constants.Constants;
import com.rex.saas.db.entity.*;
import com.rex.saas.enums.DeviceOptTypeEnum;
import com.rex.saas.enums.DeviceTypeEnum;
import com.rex.saas.service.*;
import com.rex.saas.utils.JwtUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @ClassName DeviceController
 * @Description:
 * @Author: zhusiyu
 * @CreateDate: 2024/12/18 10:55	//创建时间
 */
@RestController
@Slf4j
@RequestMapping("/device")
public class DeviceController extends BaseController{
    @Autowired
    private CategoryService categoryService;

    @Autowired
    private DeviceService deviceService;

    @Autowired
    private GatewayService gatewayService;

    @Autowired
    private SpaceService spaceService;

    @Autowired
    private TslModelService tslModelService;

    @Autowired
    private DeviceOptLogService deviceOptLogService;

    @Autowired
    private RexolarApiClient rexolarApiClient;

    private static final long ONE_DAY_SECONDS = 24 * 60 * 60 * 1000;
    @PostMapping("/update/alias")
    @ResponseBody
    public BaseResponse updateAlias(HttpServletRequest request, @RequestBody DeviceUpdateAliasRequest deviceUpdateAliasRequest){
        log.info("updateAlias deviceUpdateAliasRequest:{}", deviceUpdateAliasRequest);
        if(StringUtils.isBlank(deviceUpdateAliasRequest.getDeviceName())){
            log.error("updateAlias deviceName is null, deviceUpdateAliasRequest:{}", deviceUpdateAliasRequest);
            return BaseResponse.error("参数为空", ResultCode.PARAM_ERROR);
        }
        if(StringUtils.isBlank(deviceUpdateAliasRequest.getDeviceAlias())){
            log.error("updateAlias gwAlias is null, deviceUpdateAliasRequest:{}", deviceUpdateAliasRequest);
            return BaseResponse.error("参数为空", ResultCode.PARAM_ERROR);
        }
        String token = request.getHeader("token");
        String tenantId = JwtUtils.getTenantId(token);
        String deviceName = deviceUpdateAliasRequest.getDeviceName();
        if(StringUtils.isBlank(tenantId)){
            log.error("updateAlias tenantId is null, deviceName:{}", deviceName);
            return BaseResponse.error("token异常", ResultCode.PARAM_ERROR);
        }

        SaasDeviceInfo deviceInfo = deviceService.getDeviceByName(deviceName, tenantId);
        if(deviceInfo==null){
            log.error("updateAlias getDeviceByName error, deviceName:{}", deviceName);
            return BaseResponse.error("设备不存在", ResultCode.PARAM_ERROR);
        }
        List<String> roles = JwtUtils.getRole(token);
        if(!roles.contains(Constants.TENANT_ADMIN)){
            if(!JwtUtils.getCustomerId(token).equals(deviceInfo.getCustomerId())){
                log.error("updateAlias customerId not match error, deviceName:{}", deviceName);
                return BaseResponse.error("无权限查看", ResultCode.PARAM_ERROR);
            }
        }
        String tenantToken = rexolarApiClient.getTenantToken(tenantId);
        DeviceBasicData deviceBasicData = rexolarApiClient.getDeviceByDeviceName(deviceName, tenantToken);
        if(deviceBasicData==null){
            log.error("updateAlias getDeviceByDeviceName error, deviceName:{}", deviceName);
            return BaseResponse.error("设备不存在", ResultCode.PARAM_ERROR);
        }
        return BaseResponse.ok(deviceService.updateAlias(deviceInfo.getId(), deviceUpdateAliasRequest.getDeviceAlias()));
    }
    @GetMapping("/optType")
    public BaseResponse optType(){
        return BaseResponse.ok(DeviceOptTypeEnum.getList());
    }

    @PostMapping("/log")
    @ResponseBody
    public BaseResponse getDeviceLog(HttpServletRequest request, @RequestBody DeviceLogRequest deviceLogRequest){
        log.info("getDeviceLog deviceLogRequest:{}", deviceLogRequest);
        String token = request.getHeader("token");
        String tenantId = JwtUtils.getTenantId(token);
        if(StringUtils.isBlank(tenantId)){
            log.error("getDeviceLog tenantId is null, deviceLogRequest:{}", deviceLogRequest);
            return BaseResponse.error("token异常", ResultCode.PARAM_ERROR);
        }

        if(deviceLogRequest.getPageNo()==null || deviceLogRequest.getPageNo() < 0){
            deviceLogRequest.setPageNo(0);
        }
        if(deviceLogRequest.getPageSize()==null || deviceLogRequest.getPageSize()<= 0|| deviceLogRequest.getPageSize() > 100){
            deviceLogRequest.setPageSize(20);
        }
        try {
            long end = System.currentTimeMillis();
            long start = end  - ONE_DAY_SECONDS;
            if(StringUtils.isNotBlank(deviceLogRequest.getStartTime())){
                start = DateUtil.parse(deviceLogRequest.getStartTime(), "yyyy-MM-dd HH:mm:ss").getTime();
            }else {
                deviceLogRequest.setStartTime(DateUtil.format(new Date(start), "yyyy-MM-dd HH:mm:ss"));
            }
            if(StringUtils.isNotBlank(deviceLogRequest.getEndTime())){
                end = DateUtil.parse(deviceLogRequest.getEndTime(), "yyyy-MM-dd HH:mm:ss").getTime();
            }else {
                deviceLogRequest.setEndTime(DateUtil.format(new Date(end), "yyyy-MM-dd HH:mm:ss"));
            }
            if(start > end || end - start > ONE_DAY_SECONDS){
                log.error("getDeviceLog ILLEGAL_TIME_RANGE_OVERSIZE, deviceLogRequest:{}", deviceLogRequest);
                return  BaseResponse.error("查询时间范围超过24小时", ResultCode.PARAM_ERROR);
            }

        }catch (Exception e){
            log.error("getDeviceLog ILLEGAL_TIME_FORMAT, deviceLogRequest:{}", deviceLogRequest);
            return BaseResponse.error("查询时间格式异常，正确格式 yyyy-MM-dd HH:mm:ss", ResultCode.PARAM_ERROR);
        }

        IPage<PaasDeviceOptLog> result = deviceOptLogService.selectPage(deviceLogRequest, tenantId);
        List<PaasDeviceOptLogResponse> responseList = new ArrayList<>();
        for(PaasDeviceOptLog paasDeviceOptLog : result.getRecords()){
            PaasDeviceOptLogResponse deviceOptLogResponse = new PaasDeviceOptLogResponse();
            BeanUtils.copyProperties(paasDeviceOptLog, deviceOptLogResponse);
            deviceOptLogResponse.setGmtCreate(DateUtil.format(paasDeviceOptLog.getGmtCreate(), "yyyy-MM-dd HH:mm:ss"));
            responseList.add(deviceOptLogResponse);
        }
        Page<PaasDeviceOptLogResponse> responsePage = new Page<>(deviceLogRequest.getPageNo(), deviceLogRequest.getPageSize());
        BeanUtils.copyProperties(result, responsePage);
        responsePage.setRecords(responseList);
        return BaseResponse.ok(responsePage);
    }

    @PostMapping("/delete")
    @ResponseBody
    public BaseResponse delete(HttpServletRequest request, @RequestBody DeleteDeviceRequest deleteDeviceRequest){
        log.info("delete deleteDeviceRequest:{}", deleteDeviceRequest);
        String deviceName = deleteDeviceRequest.getDeviceName();
        if(StringUtils.isBlank(deviceName)){
            log.error("delete deviceName is null,spaceInfoId:{}", deviceName);
            return BaseResponse.error("deviceName参数为空", ResultCode.PARAM_ERROR);
        }
        String token = request.getHeader("token");
        String tenantId = JwtUtils.getTenantId(token);
        if(StringUtils.isBlank(tenantId)){
            log.error("delete tenantId is null, deviceName:{}", deviceName);
            return BaseResponse.error("token异常", ResultCode.PARAM_ERROR);
        }
        DeviceBasicData deviceBasicData = rexolarApiClient.getDeviceByDeviceName(deviceName, token);
        if(deviceBasicData==null){
            log.error("delete getDeviceByDeviceName error, deviceName:{}", deviceName);
            return BaseResponse.error("设备不存在", ResultCode.PARAM_ERROR);
        }
        if(!deviceService.delete(deviceBasicData, token, tenantId)){
            log.error("delete deleteDevice error, deviceName:{}", deviceName);
            return BaseResponse.error("删除失败", ResultCode.PARAM_ERROR);
        }
        return BaseResponse.ok();
    }

    @GetMapping("list/v2")
    public BaseResponse listV2(HttpServletRequest request, @RequestBody DeviceListRequest deviceListRequest){
        log.info("listV2 ===> deviceListRequest:{}", deviceListRequest);
        String token = request.getHeader("token");
        BaseResponse validateSpace = validateSpace(deviceListRequest.getSpaceInfoId(), token);
        if(BaseResponse.ok().getCode()!=validateSpace.getCode()){
            log.error("listV2 validateSpace fail, vaildateSpace:{}", validateSpace);
            return validateSpace;
        }
        return BaseResponse.ok(deviceService.listV2(deviceListRequest,  token));
    }
    @PostMapping("list")
    public BaseResponse list(HttpServletRequest request, @RequestBody DeviceListRequest deviceListRequest){
        log.info("list ===> deviceListRequest:{}", deviceListRequest);
        String token = request.getHeader("token");
        String tenantId = JwtUtils.getTenantId(token);
        if(StringUtils.isBlank(tenantId)){
            log.error("list tenantId is null, deviceListRequest:{}", deviceListRequest);
            return BaseResponse.error("token异常", ResultCode.PARAM_ERROR);
        }
        return BaseResponse.ok(deviceService.list(deviceListRequest.getSpaceId(), token));
    }

    @PostMapping("listPage")
    public BaseResponse listPage(HttpServletRequest request, @RequestBody DeviceListRequest deviceListRequest){
        log.info("listPage ===> deviceListRequest:{}", deviceListRequest);
        String token = request.getHeader("token");
        return BaseResponse.ok(deviceService.listPage(deviceListRequest, token));
    }

    @GetMapping("/detail")
    public BaseResponse detail(HttpServletRequest request, @RequestParam String deviceName){
        log.info("detail ===> deviceName:{}", deviceName);
        if(StringUtils.isBlank(deviceName)){
            log.error("detail deviceName is null, deviceName:{}", deviceName);
            return BaseResponse.error("deviceName参数为空", ResultCode.PARAM_ERROR);
        }
        String token = request.getHeader("token");
        String tenantId = JwtUtils.getTenantId(token);
        if(StringUtils.isBlank(tenantId)){
            log.error("detail tenantId is null, deviceId:{}", tenantId);
            return BaseResponse.error("token异常", ResultCode.PARAM_ERROR);
        }
        DeviceBasicData deviceBasicData = rexolarApiClient.getDeviceByDeviceName(deviceName, token);
        if(deviceBasicData==null){
            log.error("detail getDeviceByDeviceName error, deviceName:{}", deviceName);
            return BaseResponse.error("设备不存在", ResultCode.PARAM_ERROR);
        }
        DeviceDetailResponse devicesResponse = deviceService.detail(deviceBasicData, token);
        if(devicesResponse==null){
            log.error("detail devicesResponse is null, deviceName:{}", deviceName);
            return BaseResponse.error("设备不存在", ResultCode.PARAM_ERROR);
        }
        return BaseResponse.ok(devicesResponse);
    }

    @GetMapping("/detail/v2")
    public BaseResponse detailV2(HttpServletRequest request, @RequestParam String deviceName){
        log.info("detailV2 ===> deviceName:{}", deviceName);
        if(StringUtils.isBlank(deviceName)){
            log.error("detailV2 deviceName is null, deviceName:{}", deviceName);
            return BaseResponse.error("deviceName参数为空", ResultCode.PARAM_ERROR);
        }
        String token = request.getHeader("token");
        String tenantId = JwtUtils.getTenantId(token);
        if(StringUtils.isBlank(tenantId)){
            log.error("detailV2 tenantId is null, deviceId:{}", tenantId);
            return BaseResponse.error("token异常", ResultCode.PARAM_ERROR);
        }
        SaasDeviceInfo device = deviceService.getDeviceByName(deviceName, tenantId);
        if(device==null){
            log.error("detailV2 deviceName is not exist, deviceName:{}", deviceName);
            return BaseResponse.error("设备不存在", ResultCode.PARAM_ERROR);
        }
        if (!device.getTenantId().equals(tenantId)){
            log.error("detailV2 device tenantId not match, tenantId:{}, device:{}", tenantId, device);
            return BaseResponse.error("非法设备", ResultCode.PARAM_ERROR);
        }
        String[] names = deviceName.split("_");
        if(names.length==2){
            DeviceBasicData deviceBasicData = rexolarApiClient.getDeviceByDeviceName(names[1], token);
            if(deviceBasicData==null){
                log.error("detailV2 getDeviceByDeviceName error, deviceName:{}", deviceName);
                return BaseResponse.error("设备不存在", ResultCode.PARAM_ERROR);
            }
        }

        DeviceDetailResponseV2 devicesResponse = deviceService.detailV2(device, token);
        if(devicesResponse==null){
            log.error("detailV2 devicesResponse is null, deviceName:{}", deviceName);
            return BaseResponse.error("设备不存在", ResultCode.PARAM_ERROR);
        }
        return BaseResponse.ok(devicesResponse);
    }
    @PostMapping("/latestTimeSeries")
    public BaseResponse latestTimeSeries(HttpServletRequest request, @RequestBody DeviceLatestTimeSeriesRequest deviceLatestTimeSeriesRequest){
        log.info("latestTimeSeries ===> deviceLatestTimeSeriesRequest:{}", deviceLatestTimeSeriesRequest);
        String token = request.getHeader("token");
        String tenantId = JwtUtils.getTenantId(token);
        if(StringUtils.isBlank(tenantId)){
            log.error("latestTimeSeries tenantId is null, deviceLatestTimeSeriesRequest:{}", deviceLatestTimeSeriesRequest);
            return BaseResponse.error("token异常", ResultCode.PARAM_ERROR);
        }
        if(StringUtils.isBlank(deviceLatestTimeSeriesRequest.getDeviceName())){
            log.error("latestTimeSeries deviceName is null, deviceLatestTimeSeriesRequest:{}", deviceLatestTimeSeriesRequest);
            return BaseResponse.error("deviceName参数为空", ResultCode.PARAM_ERROR);
        }
        if(CollectionUtils.isEmpty(deviceLatestTimeSeriesRequest.getKeys())){
            log.error("latestTimeSeries keys is null, deviceLatestTimeSeriesRequest:{}", deviceLatestTimeSeriesRequest);
            return BaseResponse.error("keys参数为空", ResultCode.PARAM_ERROR);
        }
        String tenantToken = getCustomerDevTenantToken(token, deviceLatestTimeSeriesRequest.getDeviceName());
        if(StringUtils.isBlank(tenantToken)){
            log.error("latestTimeSeries tenantToken is null, deviceLatestTimeSeriesRequest:{}", deviceLatestTimeSeriesRequest);
            return BaseResponse.error("租户token异常", ResultCode.SYSTEM_ERROR);
        }
        DeviceBasicData deviceBasicData = rexolarApiClient.getDeviceByDeviceName(deviceLatestTimeSeriesRequest.getDeviceName(), tenantToken);
        if (deviceBasicData==null){
            log.error("latestTimeSeries getDeviceByDeviceName error, deviceName:{}", deviceLatestTimeSeriesRequest.getDeviceName());
            return BaseResponse.error("设备不存在", ResultCode.PARAM_ERROR);
        }
        return BaseResponse.ok(deviceService.latestTimeSeries(deviceBasicData, token, deviceLatestTimeSeriesRequest.getKeys()));
    }
    @PostMapping("/timeSeries")
    public BaseResponse timeSeries(HttpServletRequest request, @RequestBody DeviceTimeSeriesRequest deviceTimeSeriesRequest){
        log.info("timeSeries ===> deviceTimeSeriesRequest:{}", deviceTimeSeriesRequest);
        String token = request.getHeader("token");
        String tenantId = JwtUtils.getTenantId(token);
        if(StringUtils.isBlank(tenantId)){
            log.error("timeSeries tenantId is null, deviceTimeSeriesRequest:{}", deviceTimeSeriesRequest);
            return BaseResponse.error("token异常", ResultCode.PARAM_ERROR);
        }
        if(StringUtils.isBlank(deviceTimeSeriesRequest.getDeviceName())){
            log.error("timeSeries deviceName is null, deviceTimeSeriesRequest:{}", deviceTimeSeriesRequest);
            return BaseResponse.error("deviceName参数为空", ResultCode.PARAM_ERROR);
        }
        String tenantToken = getCustomerDevTenantToken(token, deviceTimeSeriesRequest.getDeviceName());
        if(StringUtils.isBlank(tenantToken)){
            log.error("timeSeries tenantToken is null, deviceTimeSeriesRequest:{}", deviceTimeSeriesRequest);
            return BaseResponse.error("租户token异常", ResultCode.PARAM_ERROR);
        }
        DeviceBasicData deviceBasicData = rexolarApiClient.getDeviceByDeviceName(deviceTimeSeriesRequest.getDeviceName(), tenantToken);
        if (deviceBasicData==null){
            log.error("timeSeries getDeviceByDeviceName error, deviceTimeSeriesRequest:{}", deviceTimeSeriesRequest);
            return BaseResponse.error("设备不存在", ResultCode.PARAM_ERROR);
        }
        if(deviceTimeSeriesRequest.getEndTime()==null){
            log.error("timeSeries endTime is null, deviceTimeSeriesRequest:{}", deviceTimeSeriesRequest);
            return BaseResponse.error("endTime参数为空", ResultCode.PARAM_ERROR);
        }
        if(deviceTimeSeriesRequest.getStartTime()==null){
            log.error("timeSeries startTime is null, deviceTimeSeriesRequest:{}", deviceTimeSeriesRequest);
            return BaseResponse.error("startTime参数为空", ResultCode.PARAM_ERROR);
        }
        if(StringUtils.isBlank(deviceTimeSeriesRequest.getKey())){
            log.error("timeSeries key is null, deviceTimeSeriesRequest:{}", deviceTimeSeriesRequest);
            return BaseResponse.error("key参数为空", ResultCode.PARAM_ERROR);
        }
        try {
            DateTime startTime = DateUtil.parseDateTime(deviceTimeSeriesRequest.getStartTime());
            DateTime endTime = DateUtil.parseDateTime(deviceTimeSeriesRequest.getEndTime());
            if(startTime.equals(endTime) || startTime.isAfter(endTime)){
                log.error("deviceTimeSeries startTime and endTime error, deviceTimeSeriesRequest:{}", deviceTimeSeriesRequest);
                return BaseResponse.error("startTime和endTime参数异常", ResultCode.PARAM_ERROR);
            }
            DeviceTimeSeriesResponse deviceTimeSeriesResponse = deviceService.timeSeries(deviceTimeSeriesRequest, token,
                    startTime.getTime(), endTime.getTime(), deviceBasicData.getCoreId());
            return BaseResponse.ok(deviceTimeSeriesResponse);

        }catch (Exception e){
            log.error("timeSeries startTime and endTime error, deviceTimeSeriesRequest:{}", deviceTimeSeriesRequest);
            return BaseResponse.error("startTime和endTime参数异常", ResultCode.PARAM_ERROR);
        }
    }

    @PostMapping("/permitAllJoin")
    @ResponseBody
    public BaseResponse permitAllJoin(HttpServletRequest request, @RequestBody PermitAllJoinRequest permitAllJoinRequest) {
        log.info("permitAllJoin ===> permitAllJoinRequest:{}", permitAllJoinRequest);
        String token = request.getHeader("token");
        String tenantId = JwtUtils.getTenantId(token);
        if(StringUtils.isBlank(tenantId)){
            log.error("permitAllJoin tenantId is null, permitAllJoinRequest:{}", permitAllJoinRequest);
            return BaseResponse.error("token异常", ResultCode.PARAM_ERROR);
        }
        if(StringUtils.isBlank(permitAllJoinRequest.getDeviceName())){
            log.error("permitAllJoin deviceName is null, permitAllJoinRequest:{}", permitAllJoinRequest);
            return BaseResponse.error("deviceName参数为空", ResultCode.PARAM_ERROR);
        }
        if(StringUtils.isBlank(permitAllJoinRequest.getDuration())){
            log.error("permitAllJoin duration is null, permitAllJoinRequest:{}", permitAllJoinRequest);
            return BaseResponse.error("duration参数为空", ResultCode.PARAM_ERROR);
        }
        DeviceBasicData gw = rexolarApiClient.getDeviceByDeviceName(permitAllJoinRequest.getDeviceName(), token);
        if(gw==null){
            log.error("permitAllJoin gw is null, permitAllJoinRequest:{}", permitAllJoinRequest);
            return BaseResponse.error("设备不存在", ResultCode.PARAM_ERROR);
        }
        Map<String, String> deviceProfiles = rexolarApiClient.getDeviceProfiles(token);
        if(deviceProfiles==null){
            log.error("permitAllJoin deviceProfiles is null, deviceName:{}", permitAllJoinRequest.getDeviceName());
            return BaseResponse.error("设备配置不存在", ResultCode.PARAM_ERROR);
        }
        String profileName = deviceProfiles.get(gw.getProfileId());
        if(StringUtils.isBlank(profileName) || (!profileName.contains("网关") && !profileName.contains(Constants.GW_ZIGBEE))){
            log.error("permitAllJoin profileName is:{}", profileName);
            return BaseResponse.error("设备类型为网关，不允许添加子设备", ResultCode.PARAM_ERROR);
        }
        boolean result = deviceService.permitAllJoin(permitAllJoinRequest, token, gw.getCoreId());
        if(!result){
            log.error("permitAllJoin error, permitAllJoinRequest:{}", permitAllJoinRequest);
        }
        return BaseResponse.ok(result);
    }

    @PostMapping("/unbindSubDevice")
    @ResponseBody
    public BaseResponse unbindSubDevice(HttpServletRequest request, @RequestBody UnbindSubDeviceRequest unbindSubDeviceRequest) {
        log.info("unbindSubDevice ===> unbindSubDeviceRequest:{}", unbindSubDeviceRequest);
        String token = request.getHeader("token");
        String tenantId = JwtUtils.getTenantId(token);
        if(StringUtils.isBlank(tenantId)){
            log.error("unbindSubDevice tenantId is null, unbindSubDevice:{}", unbindSubDeviceRequest);
            return BaseResponse.error("token异常", ResultCode.PARAM_ERROR);
        }
        if(StringUtils.isBlank(unbindSubDeviceRequest.getDeviceName())){
            log.error("unbindSubDevice deviceId is null, unbindSubDevice:{}", unbindSubDeviceRequest);
            return BaseResponse.error("deviceName参数为空", ResultCode.PARAM_ERROR);
        }
        if(CollectionUtils.isEmpty(unbindSubDeviceRequest.getSubDeviceNameList())){
            log.error("unbindSubDevice subDeviceNameList is null, unbindSubDevice:{}", unbindSubDeviceRequest);
            return BaseResponse.error("subDeviceNameList参数为空", ResultCode.PARAM_ERROR);
        }
        DeviceBasicData deviceBasicData = rexolarApiClient.getDeviceByDeviceName(unbindSubDeviceRequest.getDeviceName(), token);
        if (deviceBasicData==null){
            log.error("unbindSubDevice getDeviceByDeviceName error, deviceName:{}", unbindSubDeviceRequest.getDeviceName());
            return BaseResponse.error("设备不存在", ResultCode.PARAM_ERROR);
        }
        Map<String, String> deviceProfiles = rexolarApiClient.getDeviceProfiles(token);
        if(deviceProfiles==null){
            log.error("unbindSubDevice deviceProfiles is null, deviceName:{}", unbindSubDeviceRequest.getDeviceName());
            return BaseResponse.error("设备配置不存在", ResultCode.PARAM_ERROR);
        }
        String profileName = deviceProfiles.get(deviceBasicData.getProfileId());
        if(StringUtils.isBlank(profileName) && !profileName.contains("网关配置") && !profileName.contains("Zigbee网关")){
            log.error("unbindSubDevice profileName is:{}", profileName);
            return BaseResponse.error("设备类型非网关 ", ResultCode.PARAM_ERROR);
        }

        if(unbindSubDeviceRequest.getSubDeviceNameList().size()>100){
            log.error("unbindSubDevice subDeviceList size is:{}", unbindSubDeviceRequest.getSubDeviceNameList().size());
            return BaseResponse.error("subDeviceList参数不能大于100", ResultCode.PARAM_ERROR);
        }


        boolean result = deviceService.unbindSubDevice(unbindSubDeviceRequest, token, deviceBasicData.getCoreId());
        if(!result){
            log.error("unbindSubDevice error, unbindSubDeviceRequest:{}", unbindSubDeviceRequest);
        }
        return BaseResponse.ok(result);
    }

    @PostMapping("/readDevProperty")
    @ResponseBody
    public BaseResponse readDevProperty(HttpServletRequest request, @RequestBody ReadDevPropertyRequest readDevPropertyRequest) {
        log.info("readDevProperty ===> readDevPropertyRequest:{}", readDevPropertyRequest);
        String token = request.getHeader("token");
        String tenantId = JwtUtils.getTenantId(token);
        if(StringUtils.isBlank(tenantId)){
            log.error("readDevProperty tenantId is null, readDevPropertyRequest:{}", readDevPropertyRequest);
            return BaseResponse.error("token异常", ResultCode.PARAM_ERROR);
        }
        if(StringUtils.isBlank(readDevPropertyRequest.getDeviceName())){
            log.error("readDevProperty deviceName is null, readDevPropertyRequest:{}", readDevPropertyRequest);
            return BaseResponse.error("deviceName参数为空", ResultCode.PARAM_ERROR);
        }
        DeviceBasicData deviceBasicData = rexolarApiClient.getDeviceByDeviceName(readDevPropertyRequest.getDeviceName(), token);
        if(deviceBasicData==null){
            log.error("readDevProperty deviceBasicData is null, readDevPropertyRequest:{}", readDevPropertyRequest);
            return BaseResponse.error("设备不存在", ResultCode.PARAM_ERROR);
        }

        if(StringUtils.isBlank(readDevPropertyRequest.getProperty())){
            log.error("readDevProperty property is null, readDevPropertyRequest:{}", readDevPropertyRequest);
            return BaseResponse.error("property参数为空", ResultCode.PARAM_ERROR);
        }
        Map<String, String> deviceProfiles = rexolarApiClient.getDeviceProfiles(token);
        String profileName = deviceProfiles.get(deviceBasicData.getProfileId());
        boolean result = false;
        if(profileName!=null && profileName.equals("lightDevice")){
            log.info("readLightDeviceProperty ===> readDevPropertyRequest:{}", readDevPropertyRequest);
            result = deviceService.readLightDeviceProperty(deviceBasicData, token, readDevPropertyRequest.getProperty());
            if(!result){
                log.error("readLightDeviceProperty error, readDevPropertyRequest:{}", readDevPropertyRequest);
            }
        }else {
            log.info("readDevProperty ===> readDevPropertyRequest:{}", readDevPropertyRequest);
            result = deviceService.readDevProperty(deviceBasicData, token, readDevPropertyRequest.getProperty());
            if(!result){
                log.error("readDevProperty error, readDevPropertyRequest:{}", readDevPropertyRequest);
            }
        }

        return BaseResponse.ok(result);
    }

    @PostMapping("/writeDevProperty")
    @ResponseBody
    public BaseResponse writeDevProperty(HttpServletRequest request, @RequestBody WriteDevPropertyRequest writeDevPropertyRequest) {
        log.info("writeDevProperty ===> writeDevPropertyRequest:{}", writeDevPropertyRequest);
        String token = request.getHeader("token");
        String tenantId = JwtUtils.getTenantId(token);
        if(StringUtils.isBlank(tenantId)){
            log.error("writeDevProperty tenantId is null, writeDevPropertyRequest:{}", writeDevPropertyRequest);
            return BaseResponse.error("token异常", ResultCode.PARAM_ERROR);
        }
        if(StringUtils.isBlank(writeDevPropertyRequest.getDeviceName())){
            log.error("writeDevProperty deviceName is null, writeDevPropertyRequest:{}", writeDevPropertyRequest);
            return BaseResponse.error("deviceName参数为空", ResultCode.PARAM_ERROR);
        }
        if(StringUtils.isBlank(writeDevPropertyRequest.getProperty())){
            log.error("writeDevProperty property is null, writeDevPropertyRequest:{}", writeDevPropertyRequest);
            return BaseResponse.error("property参数为空", ResultCode.PARAM_ERROR);
        }
        if(StringUtils.isBlank(writeDevPropertyRequest.getValue())){
            log.error("writeDevProperty value is null, writeDevPropertyRequest:{}", writeDevPropertyRequest);
            return BaseResponse.error("value", ResultCode.PARAM_ERROR);
        }
        String tenantToken = getCustomerDevTenantToken(token, writeDevPropertyRequest.getDeviceName());
        if(tenantToken==null){
            log.error("writeDevProperty tenantToken is null, writeDevPropertyRequest:{}", writeDevPropertyRequest);
            return BaseResponse.error("token异常", ResultCode.PARAM_ERROR);
        }

        DeviceBasicData deviceBasicData = rexolarApiClient.getDeviceByDeviceName(writeDevPropertyRequest.getDeviceName(), tenantToken);
        if(deviceBasicData==null){
            log.error("writeDevProperty deviceBasicData is null, writeDevPropertyRequest:{}", writeDevPropertyRequest);
            return BaseResponse.error("设备不存在", ResultCode.PARAM_ERROR);
        }
        if(StringUtils.isBlank(writeDevPropertyRequest.getGroupId())){
            writeDevPropertyRequest.setGroupId("0");
        }
        Map<String, String> deviceProfiles = rexolarApiClient.getDeviceProfiles(tenantToken);
        String profileName = deviceProfiles.get(deviceBasicData.getProfileId());
        boolean result = false;
        if(profileName!=null && profileName.equals("lightDevice")){
            result = deviceService.writeLightDevProperty(deviceBasicData, token, writeDevPropertyRequest);
            if(!result){
                log.error("writeDevProperty writeLightDevProperty error, writeDevProperty:{}", writeDevPropertyRequest);
            }
        }else {
            result = deviceService.writeDevProperty(deviceBasicData, token, writeDevPropertyRequest);
            if(!result){
                log.error("writeDevProperty error, writeDevProperty:{}", writeDevPropertyRequest);
            }
        }

        return BaseResponse.ok(result);
    }

    @PostMapping("/invokeDevCommand")
    @ResponseBody
    public BaseResponse invokeDevCommand(HttpServletRequest request, @RequestBody InvokeDevCommandRequest invokeDevCommandRequest) {
        log.info("invokeDevCommand ===> invokeDevCommandRequest:{}", invokeDevCommandRequest);
        String token = request.getHeader("token");
        String tenantId = JwtUtils.getTenantId(token);
        if(StringUtils.isBlank(tenantId)){
            log.error("invokeDevCommand tenantId is null, invokeDevCommandRequest:{}", invokeDevCommandRequest);
            return BaseResponse.error("token异常", ResultCode.PARAM_ERROR);
        }
        if(StringUtils.isBlank(invokeDevCommandRequest.getDeviceName())){
            log.error("invokeDevCommand gwName is null, invokeDevCommandRequest:{}", invokeDevCommandRequest);
            return BaseResponse.error("deviceName参数为空", ResultCode.PARAM_ERROR);
        }
        if(invokeDevCommandRequest.getInvoke()==null){
            log.error("invokeDevCommand property is null, invokeDevCommandRequest:{}", invokeDevCommandRequest);
            return BaseResponse.error("property参数为空", ResultCode.PARAM_ERROR);
        }
        DeviceBasicData deviceBasicData = rexolarApiClient.getDeviceByDeviceName(invokeDevCommandRequest.getDeviceName(), token);
        if(deviceBasicData==null){
            log.error("invokeDevCommand deviceBasicData is null, invokeDevCommandRequest:{}", invokeDevCommandRequest);
            return BaseResponse.error("设备不存在", ResultCode.PARAM_ERROR);
        }

        if(StringUtils.isBlank(invokeDevCommandRequest.getGroupId())){
            invokeDevCommandRequest.setGroupId("0");
        }

        boolean result = deviceService.invokeDevCommand(deviceBasicData, token, invokeDevCommandRequest);
        if(!result){
            log.error("invokeDevCommand error, invokeDevCommandRequest:{}", invokeDevCommandRequest);
        }
        return BaseResponse.ok(result);
    }


    @PostMapping("/updateAttributes")
    @ResponseBody
    public BaseResponse updateAttributes(HttpServletRequest request, @RequestBody WriteDevPropertyRequest writeDevPropertyRequest) {
        log.info("updateAttributes ===> updateAttributes:{}", writeDevPropertyRequest);
        String token = request.getHeader("token");
        if(StringUtils.isBlank(writeDevPropertyRequest.getDeviceName())){
            log.error("updateAttributes gwName is null, readDevPropertyRequest:{}", writeDevPropertyRequest);
            return BaseResponse.error("deviceName参数为空", ResultCode.PARAM_ERROR);
        }
        if(StringUtils.isBlank(writeDevPropertyRequest.getProperty())){
            log.error("updateAttributes property is null, readDevPropertyRequest:{}", writeDevPropertyRequest);
            return BaseResponse.error("property参数为空", ResultCode.PARAM_ERROR);
        }
        if(StringUtils.isBlank(writeDevPropertyRequest.getValue())){
            log.error("updateAttributes value is null, readDevPropertyRequest:{}", writeDevPropertyRequest);
            return BaseResponse.error("value", ResultCode.PARAM_ERROR);
        }
        DeviceBasicData deviceBasicData = rexolarApiClient.getDeviceByDeviceName(writeDevPropertyRequest.getDeviceName(), token);
        if(deviceBasicData==null){
            log.error("updateAttributes deviceBasicData is null, readDevPropertyRequest:{}", writeDevPropertyRequest);
            return BaseResponse.error("设备不存在", ResultCode.PARAM_ERROR);
        }

        boolean result = deviceService.updateAttributes(deviceBasicData, token, writeDevPropertyRequest.getProperty(), writeDevPropertyRequest.getValue());
        if(!result){
            log.error("updateAttributes error, writeDevProperty:{}", writeDevPropertyRequest);
        }
        return BaseResponse.ok(result);
    }

    @PostMapping("/attributes")
    public BaseResponse attributes(HttpServletRequest request, @RequestBody DeviceAttributesRequest deviceAttributesRequest){
        log.info("attributes ===> deviceAttributesRequest:{}", deviceAttributesRequest);
        String token = request.getHeader("token");
        if(StringUtils.isBlank(deviceAttributesRequest.getDeviceName())){
            log.error("attributes gwName is null, deviceAttributesRequest:{}", deviceAttributesRequest);
            return BaseResponse.error("deviceName参数为空", ResultCode.PARAM_ERROR);
        }
        if(deviceAttributesRequest.getKeys()==null || deviceAttributesRequest.getKeys().isEmpty()){
            log.error("attributes keys is null, deviceAttributesRequest:{}", deviceAttributesRequest);
            return BaseResponse.error("keys参数为空", ResultCode.PARAM_ERROR);
        }
        String tenantToken = rexolarApiClient.getTenantToken(JwtUtils.getTenantId(token));
        if (StringUtils.isBlank(tenantToken)){
            log.error("attributes getTenantToken error, tenantId:{}", JwtUtils.getTenantId(token));
            return BaseResponse.error("获取租户token异常", ResultCode.PARAM_ERROR);
        }
        DeviceBasicData deviceBasicData = rexolarApiClient.getDeviceByDeviceName(deviceAttributesRequest.getDeviceName(), tenantToken);
        if(deviceBasicData==null){
            log.error("attributes getDeviceByDeviceName error, gwName:{}", deviceAttributesRequest.getDeviceName());
            return BaseResponse.error("设备不存在", ResultCode.PARAM_ERROR);
        }

        DeviceAtrributesResponse deviceAtrributesResponse = deviceService.attributes(deviceBasicData, deviceAttributesRequest, token);
        return BaseResponse.ok(deviceAtrributesResponse);
    }

    @PostMapping("rssiInfo")
    public BaseResponse rssiInfo(HttpServletRequest request, @RequestBody DeviceListRequest deviceListRequest){
        log.info("rssiInfo ===> deviceListRequest:{}", deviceListRequest);
        String token = request.getHeader("token");
        return BaseResponse.ok(deviceService.rssiInfo(deviceListRequest, token));
    }

    @GetMapping("alarms")
    public BaseResponse alarms(HttpServletRequest request){
        String token = request.getHeader("token");
        return BaseResponse.ok(deviceService.alarms(token));
    }

    @PostMapping("/customer/list")
    public BaseResponse customerList(HttpServletRequest request, @RequestBody DeviceListRequest deviceListRequest){
        log.info("customerList ===> deviceListRequest:{}", deviceListRequest);
        String token = request.getHeader("token");
        return BaseResponse.ok(deviceService.customerList(deviceListRequest, token));
    }

    @GetMapping("/reset")
    public BaseResponse reset(HttpServletRequest request, @RequestParam String deviceName){
        log.info("reset ===> deviceName:{}", deviceName);
        String token = request.getHeader("token");
        BaseResponse baseResponse = validateDeviceName(deviceName, token);
        if(!baseResponse.isSuccess()){
            log.error("reset validateDeviceName error, deviceName:{}", deviceName);
            return baseResponse;
        }
        return BaseResponse.ok(deviceService.reset(deviceName, token));
    }

    @GetMapping("syncGw")
    public BaseResponse syncGw(HttpServletRequest request){
        String token = request.getHeader("token");
        List<String> roles = JwtUtils.getRole(token);
        if(!roles.contains(Constants.TENANT_ADMIN)){
            log.error("syncGw error, SYSTEM_ADMIN");
            return BaseResponse.error("权限不足", ResultCode.PARAM_ERROR);
        }

        return BaseResponse.ok(deviceService.syncGw(token));
    }

    @PostMapping("/add")
    public BaseResponse add(HttpServletRequest request, @RequestBody DeviceAddRequest deviceAddRequest){
        log.info("add ===> deviceAddRequest:{}", deviceAddRequest);
        String token = request.getHeader("token");
        if (deviceAddRequest.getSpaceInfoId()==null){
            log.error("add spaceInfoId is null, deviceAddRequest:{}", deviceAddRequest);
            return BaseResponse.error("spaceInfoId参数为空", ResultCode.PARAM_ERROR);
        }
        if (StringUtils.isBlank(deviceAddRequest.getDeviceName())){
            log.error("add deviceName is null, deviceAddRequest:{}", deviceAddRequest);
            return BaseResponse.error("deviceName参数为空", ResultCode.PARAM_ERROR);
        }
        String deviceName = deviceAddRequest.getDeviceName();
        String[] names = deviceAddRequest.getDeviceName().split("_");
        if (names.length==2){
            deviceName = names[1];
        }
        SaasDeviceInfo deviceInfo = deviceService.getDeviceByName(deviceName, JwtUtils.getTenantId(token));
        if (deviceInfo!=null){
            log.error("add deviceName is exist, deviceName:{}", deviceAddRequest.getDeviceName());
            return BaseResponse.error("设备已存在", ResultCode.PARAM_ERROR);
        }
        DeviceBasicData deviceBasicData =  rexolarApiClient.getDeviceByDeviceName(deviceName, token);
        if (deviceBasicData==null){
            log.error("add deviceBasicData is null, deviceName:{}", deviceName);
            return BaseResponse.error("设备不存在", ResultCode.PARAM_ERROR);
        }
        if (deviceAddRequest.getGwId()!=null){
            PaasGatewayCredentials gateway =gatewayService.getById(deviceAddRequest.getGwId());
            if (gateway==null){
                log.error("add gateway is null, gatewayId:{}", deviceAddRequest.getGwId());
                return BaseResponse.error("网关不存在", ResultCode.PARAM_ERROR);
            }
        }
        SaasSpaceInfo spaceInfo = spaceService.getSpaceById(deviceAddRequest.getSpaceInfoId());
        if(spaceInfo==null){
            log.error("add spaceInfo is null, spaceInfoId:{}", deviceAddRequest.getSpaceInfoId());
            return BaseResponse.error("spaceInfoId参数错误", ResultCode.PARAM_ERROR);
        }
        if (!spaceInfo.getTenantId().equals(JwtUtils.getTenantId(token))){
            log.error("add spaceInfo tenantId not match, tenantId:{}, spaceInfo:{}", JwtUtils.getTenantId(token), spaceInfo);
            return BaseResponse.error("非法空间", ResultCode.PARAM_ERROR);
        }
//        List<SaasTslModel> product = tslModelService.queryTslModelByPK(deviceAddRequest.getProductKey(), JwtUtils.getTenantId(token));
//        if (CollectionUtils.isEmpty(product)){
//            log.error("add product is null, productKey:{}", deviceAddRequest.getProductKey());
//            return BaseResponse.error("产品不存在", ResultCode.PARAM_ERROR);
//        }
        String profile = "default";
        DeviceInfoData deviceInfoData = new DeviceInfoData();
        BeanUtils.copyProperties(deviceAddRequest, deviceInfoData);
        deviceInfoData.setSpaceInfoId(deviceAddRequest.getSpaceInfoId());
        deviceInfoData.setSpaceCoreId(spaceInfo.getCoreId());
        deviceInfoData.setCategoryName(profile);
        CategroyResponse categroyResponse = categoryService.getDetailsByName(token, profile);
        if(categroyResponse!=null){
            deviceInfoData.setCategoryId(categroyResponse.getCategoryId());
        }
        deviceInfoData.setCoreId(deviceBasicData.getCoreId());
        deviceInfoData.setTenantId(JwtUtils.getTenantId(token));
        deviceInfoData.setType(DeviceTypeEnum.SUB_DEVICE.getCode());
        boolean flag = deviceService.addSubDevice(deviceInfoData);
        if (!flag){
            log.error("add error, deviceInfoData:{}", deviceInfoData);
            return BaseResponse.error("添加设备异常", ResultCode.PARAM_ERROR);
        }
        return BaseResponse.ok(flag);
    }

    @PostMapping("/setPosition")
    @ResponseBody
    public BaseResponse setPosition(HttpServletRequest request, @RequestBody DeviceSetPositionRequest deviceSetPositionRequest){
        log.info("setPosition ===> deviceSetPositionRequest:{}", deviceSetPositionRequest);
        String token = request.getHeader("token");
        if(StringUtils.isBlank(deviceSetPositionRequest.getDeviceName())){
            log.error("setPosition deviceName is null, deviceSetPositionRequest:{}", deviceSetPositionRequest);
            return BaseResponse.error("参数为空", ResultCode.PARAM_ERROR);
        }
        if(deviceSetPositionRequest.getSpaceInfoId()==null){
            log.error("setPosition spaceInfoId is null, deviceSetPositionRequest:{}", deviceSetPositionRequest);
            return BaseResponse.error("参数为空", ResultCode.PARAM_ERROR);
        }
        if (StringUtils.isBlank(deviceSetPositionRequest.getPosition())){
            log.error("setPosition position is null, deviceSetPositionRequest:{}", deviceSetPositionRequest);
            return BaseResponse.error("参数为空", ResultCode.PARAM_ERROR);
        }
        if (StringUtils.isBlank(deviceSetPositionRequest.getRouter())){
            log.error("setPosition router is null, deviceSetPositionRequest:{}", deviceSetPositionRequest);
            return BaseResponse.error("参数为空", ResultCode.PARAM_ERROR);
        }
        BaseResponse baseResponse = validateDeviceName(deviceSetPositionRequest.getDeviceName(), token);
        if(!baseResponse.isSuccess()){
            log.error("setPosition validateDeviceName error, deviceName:{}", deviceSetPositionRequest.getDeviceName());
            return baseResponse;
        }
        baseResponse = validateSpace(deviceSetPositionRequest.getSpaceInfoId(), token);
        if(!baseResponse.isSuccess()){
            log.error("setPosition validateSpace error, spaceId:{}", deviceSetPositionRequest.getSpaceInfoId());
            return baseResponse;
        }
        return BaseResponse.ok(deviceService.setPosition(deviceSetPositionRequest, token));
    }

}
